#include "BlockRenderer.h"
#include "vector3.h"
#include "base.h"
#include "stdGeom.h"
#include "Utils.h"
#include "Constant.h"
#include "Renderer.h"
BlockRenderer::BlockRenderer(void)
{
}
BlockRenderer::~BlockRenderer(void)
{
	Delete(m_pTextures);
}
void BlockRenderer::DrawBlockAlt(vector3 position, uint blockID)
{
	matrix trans = matrix::Translation(vector3(position.x, position.y, position.z));
	m_shaderSolid.SetWorld(trans);

	const MultiTextureIndex &mti = m_pBlocks->GetBlockTextureInfo(blockID);

	for(int i = 0; i < SIDE_COUNT; i++)
	{
		m_shaderSolid.SetTextureIndex(mti.GetUV(i));
		m_blockModel.RenderBlockSide(i);
	}
}
void BlockRenderer::DrawChunkBlocksInstanced(Chunk *pChunk)
{
}
void BlockRenderer::BeginBlockDrawingAlt()
{
	m_shaderSolid.Bind();
	//m_shaderSolid.SetProjection(matrix::CenteredOrthogonal(10.0f, 10.0f, 0.1f, 100.0f));
	m_shaderSolid.SetProjection(m_pCamera->GetProjection());
	m_shaderSolid.SetView(m_pCamera->GetViewMatrix());
	m_shaderSolid.SetTexture(m_pTextures->GetTextureObject(m_nTerrainTexture));

	m_blockModel.SetCustomPointers(m_shaderSolid.GetVertexLocation(), m_shaderSolid.GetNormalLocation(), m_shaderSolid.GetTexcoordLocation());

	//Check block side visibility
	vector3 camDir = m_pCamera->GetDirection();
	//float dotTop = camDir.Dot(cubeFaceNormals[SIDE_TOP]);
	//float dotFront = camDir.Dot(cubeFaceNormals[SIDE_FRONT]);
	//float dotRight = camDir.Dot(cubeFaceNormals[SIDE_RIGHT]);

	glEnable(GL_DEPTH_TEST);
	glEnable(GL_CULL_FACE);
	glCullFace(GL_BACK);
}
void BlockRenderer::SetCamera(boost::shared_ptr<ICamera> pCamera)
{
	m_pCamera = pCamera;
}
boost::shared_ptr<ICamera> BlockRenderer::GetCamera()
{
	return m_pCamera;
}
void BlockRenderer::EndBlockDrawingAlt()
{
	m_shaderSolid.Unbind();
	glDisable(GL_DEPTH_TEST);
	glDisable(GL_CULL_FACE);
}
/*
void BlockRenderer::DrawBlock(vector3 &position, uint blockID)
{
	//Apply block transformation
	m_shaderSolid.SetWorld(matrix::Translation(vector3(position.x, position.y, position.z)));
	
	const MultiTextureIndex &mti = m_pBlocks->GetBlockTextureInfo(blockID);
	for(int i = 0; i < SIDE_COUNT; i++)
	{
		//mti[i];
		m_blockModel.RenderBlockSide(i);
	}
	glErrorCheck();
}
void BlockRenderer::BeginBlockDrawing(const matrix &projection, const matrix &view, uint nTerrainTexture)
{
	//Bind block renderer Shader
	m_shaderSolid.Bind();
	//Bind transforms that are uniform this frame
	m_shaderSolid.SetProjection(projection);
	m_shaderSolid.SetView(view);

	m_shaderSolid.SetTexture(m_pTextures->GetTextureObject(nTerrainTexture));

	glEnable(GL_CULL_FACE);
	glCullFace(GL_BACK);
	glFrontFace(GL_CCW);
	glEnable(GL_DEPTH_TEST);
}
void BlockRenderer::EndBlockDrawing()
{
	glDisable(GL_DEPTH_TEST);
	glDisable(GL_CULL_FACE);
	m_shaderSolid.Unbind();
}*/
void BlockRenderer::Initialize(BlockLibrary *pBlocks, IRenderer *pRenderer)
{
	//Initialize texture manager
	m_pTextures = new TextureManager();
	string imagePath = current_path().string() + "\\" + PATH_IMGDIR;
	m_pTextures->Initialize(imagePath);
	m_pBlocks = pBlocks;

	m_pRenderer = pRenderer;
	
	//Load block model for rendering individual sides
	m_blockModel.Initialize();
	glErrorCheck();

	//Initialize shaders
	m_shaderSolid.Initialize();
	glErrorCheck();
}
void BlockRenderer::SetTerrainTexture(uint nTex)
{
	m_nTerrainTexture = nTex;
}
TextureManager *BlockRenderer::GetTextureManager()
{
	return m_pTextures;
}